package com.connector.server.config;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;

public class ExecutorServiceFactory
{
    private static ExecutorServiceFactory executorFactory;
    private ExecutorService executors;
    
    private ExecutorServiceFactory() {
    }
    
    public static ExecutorServiceFactory getInstance() {
        return ExecutorServiceFactory.executorFactory;
    }
    
    public ExecutorService createScheduledThreadPool() {
        final int availableProcessors = Runtime.getRuntime().availableProcessors();
        return this.executors = Executors.newScheduledThreadPool(availableProcessors * 10, this.getThreadFactory());
    }
    
    public ExecutorService createSingleThreadExecutor() {
        return this.executors = Executors.newSingleThreadExecutor(this.getThreadFactory());
    }
    
    public ExecutorService createCachedThreadPool() {
        return this.executors = Executors.newCachedThreadPool(this.getThreadFactory());
    }
    
    public ExecutorService createFixedThreadPool(final int count) {
        return this.executors = Executors.newFixedThreadPool(count, this.getThreadFactory());
    }
    
    private ThreadFactory getThreadFactory() {
        return new ThreadFactory() {
            AtomicInteger sn = new AtomicInteger();
            
            @Override
            public Thread newThread(final Runnable r) {
                final SecurityManager s = System.getSecurityManager();
                final ThreadGroup group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
                final Thread t = new Thread(group, r);
                t.setName("sendAsyncThread_" + this.sn.incrementAndGet());
                return t;
            }
        };
    }
    
    static {
        ExecutorServiceFactory.executorFactory = new ExecutorServiceFactory();
    }
}
